package com.liz.tectSelect.nettySpringbootRestfulApi.netty;

import com.liz.tectSelect.nettySpringbootRestfulApi.service.BaseService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

@Component
@ChannelHandler.Sharable
public class DiscardServerHandler extends SimpleChannelInboundHandler<Object> {

    @Resource
    private BaseService baseService;


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object obj) throws Exception {
        //判断msg是否为一个HttpRequest的请求类型
        if(!(obj instanceof HttpRequest)) {
            System.out.println("接收到非http的请求");
            return;
        }
//        DefaultHttpRequest httpRequest = (DefaultHttpRequest) obj;
        DefaultFullHttpRequest httpRequest = (DefaultFullHttpRequest) obj;
        // 将GET, POST所有请求参数转换成Map对象
        Map<String, String> parmMap = HttpRequestParser.parse(httpRequest);
        System.out.println(parmMap);



        try {
            //获取当前channel
            Channel currentChannel = channelHandlerContext.channel();
            //客户端远程地址
            System.out.println(currentChannel.remoteAddress());
            /*
            * 增加了判断，为何还会打印两次？
            *
            /0:0:0:0:0:0:0:1:5605
            /0:0:0:0:0:0:0:1:5605
            *
            * 打开浏览器的network会发现，客户端对服务端进行了两次请求：
            * 	1、第一次是所需的
            *  2、第二次是一个icon
            *  因为没有加路由（相当于Springmvc中的requestMapping），只要发起请求，就都会到handler中去
            */

//            ByteBuf in = (ByteBuf) msg;
//            System.out.println("传输内容是"+msg);
//            System.out.println(in.toString(CharsetUtil.UTF_8));
            System.out.println(obj);
            //这里调用service服务
            String result = baseService.test();

            //定义发送的消息（不是直接发送，而是要把数据拷贝到缓冲区，通过缓冲区）
            //Unpooed：是一个专门用于拷贝Buffer的深拷贝，可以有一个或多个
            //CharsetUtil.UTF_8：Netty提供
            ByteBuf content = Unpooled.copiedBuffer(result, CharsetUtil.UTF_8);


            //构建一个HttpResponse，响应客户端
            /**
             * params1:针对Http的版本号
             * params2:状态（响应成功或失败）
             * params3:内容
             */
            //HttpVersion.HTTP_1_1：默认开启keep-alive
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
            //通过长下文对象，把响应刷到客户端
            channelHandlerContext.writeAndFlush(response);
        }  finally {
            ReferenceCountUtil.release(obj);
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 出现异常就关闭
        cause.printStackTrace();
        ctx.close();
    }
}
